home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Personal Computer World 2005 October
/
PCWOCT05.iso
/
Software
/
Resources
/
CutePDF 2.3
/
converter.exe
/
GNUGS
/
GS_CIDFN.PS
< prev
next >
Wrap
Text File
|
2002-04-04
|
22KB
|
702 lines
% Copyright (C) 1995, 2000 Aladdin Enterprises. All rights reserved.
%
% This software is provided AS-IS with no warranty, either express or
% implied.
%
% This software is distributed under license and may not be copied,
% modified or distributed except as expressly authorized under the terms
% of the license contained in the file LICENSE in this distribution.
%
% For more information about licensing, please refer to
% http://www.ghostscript.com/licensing/. For information on
% commercial licensing, go to http://www.artifex.com/licensing/ or
% contact Artifex Software, Inc., 101 Lucas Valley Road #110,
% San Rafael, CA 94903, U.S.A., +1(415)492-9861.
% $Id: gs_cidfn.ps,v 1.18.4.5 2002/04/03 07:31:14 mpsuzuki Exp $
% ProcSet for implementing CIDFont and CIDMap resources.
% When this is run, systemdict is still writable.
% ---------------- Defining CIDFont resources ---------------- %
% Define a CIDFont resource. This is the defineresource implementation for
% the CIDFont resource category.
/.checkfonttype { % <cidfont> <fonttype> .checkfonttype <cidfont> <new?>
1 index /FID known {
1 index /FontType get ne {
/definefont cvx /invalidfont signalerror
} if false
} {
1 index /FontType 3 -1 roll put true
} ifelse
} bind def
/.cidfonttypes where { pop } { /.cidfonttypes 6 dict def } ifelse
.cidfonttypes
30 dict begin
% The key in .cidfonttypes is the CIDFontType value;
% the value is a procedure that takes a font name and the CIDFont dictionary
% and replaces the latter with a real font.
% ------ CIDFontType 0 (FontType 9) ------ %
% We add the following entries to the CIDFont dictionary, in addition to
% the ones documented by Adobe:
% SubrCache - dictionary for caching Subr arrays
% For CIDFonts where we read the data from disk incrementally:
% GlyphData is 0 (arbitrary)
% DataSource - a ReusableStreamDecode filter for the data
% We also add a FID entry, and possibly a Subrs entry, to each element of
% FDArray.
dup 0 {
9 .checkfonttype {
/CIDInit /ProcSet findresource begin
.completefont9
end
} if
1 index exch .buildfont9 exch pop
} bind put
% Add entries to a new CIDFontType 0 font per documentation (FontMatrix)
% or for .buildfont9 (FDArray.Private.Subrs).
/.completefont9 { % <cidfont0> .completefont9 <cidfont0>
currentglobal 3 1 roll dup gcheck setglobal
dup /FontMatrix known not {
dup /FontMatrix [0.001 0 0 0.001 0 0] put
dup /FDArray get {
/FontMatrix get [1000 0 0 1000 0 0] 1 index concatmatrix pop
} forall
} if
dup /FDArray get {
% Read the Subrs if necessary.
dup /Private get dup /Subrs known not {
dup /SubrCount .knownget {
% Stack: font Private SubrCount
currentglobal 3 1 roll 1 index gcheck setglobal
array 1 index /Subrs 3 -1 roll put
% Stack: font global Private
2 index begin begin .loadsubrs end end
setglobal
} {
pop
} ifelse readonly pop
} {
pop pop
} ifelse
} forall
3 -1 roll setglobal
} bind def
% Read some Subrs for the current Type 1 subfont.
% The subfont's Private dict is currentdict; the CIDFont itself is the
% next dictionary on the stack.
/.readsubrs { % <Subrs> <start> .readsubrs <Subrs>
1 SubrCount 1 sub {
dup SDBytes mul SubrMapOffset add
dup SDBytes .readint exch SDBytes add SDBytes .readint
1 index sub string ReadString 2 index 3 1 roll put
} for
} bind def
% Ensure that all the Subrs for the current Type 1 subfont are loaded.
% The subfont's Private dict is currentdict; the CIDFont itself is the
% next dictionary on the stack.
/.loadsubrs {
Subrs length 0 ne {
SubrCache SubrMapOffset .knownget {
% We've already loaded some Subrs at this offset.
% Make sure we've got as many as we need.
dup length SubrCount lt {
% We need to load more.
SubrCount array exch 1 index copy length .readsubrs
SubrCache SubrMapOffset 2 index put
} if
} {
% We haven't loaded any Subrs at this offset yet.
SubrCount array 0 .readsubrs
SubrCache SubrMapOffset 2 index put
} ifelse
Subrs copy pop
} if
} bind def
% ------ CIDFontType 1 (FontType 10) ------ %
dup 1 {
10 .checkfonttype pop
1 index exch .buildfont10 exch pop
} bind put
% ------ CIDFontType 2 (FontType 11) ------ %
dup 2 {
11 .checkfonttype pop
1 index exch .buildfont11 exch pop
} bind put
pop % .cidfonttypes
% ---------------- Reading CIDFontType 0 files ---------------- %
/StartData { % <(Binary)|(Hex)> <datalength> StartData -
% (currentdict is CID font dict)
% If we're loading a resource file and the data format is
% binary, we can just save a pointer to the data and load it
% incrementally.
mark {
% Previous versions of this code made provisions for
% reading hex-encoded data incrementally. Since hex data
% doesn't seem to be used in practice, we no longer bother.
2 index (Binary) ne { stop } if
currentfile .currentresourcefile ne { stop } if
% Hack: the pdfwrite driver relies on finalization to write
% out fonts. However, the font may be finalized after the
% resource file, in which case the resource file will be
% closed. So if the current output device is pdfwrite,
% don't use incremental loading.
currentdevice .devicename /pdfwrite eq { stop } if
currentfile fileposition
} .internalstopped {
% File is not positionable, or uses hex data.
% Load the data now.
cleartomark exch (Hex) eq
{ { currentfile exch readhexstring pop } }
{ { currentfile exch readstring pop } }
ifelse exch
% Stack: readproc length
dup 65400 le {
% readstring with a 0-length string causes a rangecheck,
% but a data length of 0 is allowed.
string dup () ne { 1 index exec } if
} {
mark 3 1 roll {
% Stack: mark str ... readproc length
dup 0 eq { pop exit } if
dup 65400 .min dup string 3 index exec
% Stack: mark str ... readproc length newstrlen newstr
4 1 roll sub
} loop
counttomark 1 add 1 roll ]
} ifelse
/GlyphData exch def
% If we were reading hex data, skip past the >.
2 get { readhexstring } 0 get eq {
currentfile 0 (>) .subfiledecode dup flushfile closefile
} if
} {
% File is positionable and binary, just save a pointer.
% Stack: (Binary) length -mark- pos
/GlyphData 0 def
exch pop 3 -1 roll pop exch
% Stack: pos length
/DataSource currentfile 2 index () .subfiledecode true .reusablestream def
currentfile 3 1 roll add setfileposition
} ifelse
/SubrCache 10 dict def
CIDFontName currentdict /CIDFont defineresource pop
end % CID font dict
end % resource category dict
} bind def
% Some Adobe fonts include the line
% /Setup /cid_Setup load def
% This is apparently included only to prevent proper, conforming PostScript
% interpreters (as opposed to ATM or a special Adobe font loader) from
% loading the font, since Setup is not referenced anywhere else in the file.
/cid_Setup { } def
currentdict end
% ---------------- Rendering ---------------- %
% ------ Generic ------ %
% Read a string at a given offset in a "file" (binary file or
% GlyphData in RAM).
/ReadString { % <pos> <string> ReadString <string>
GlyphData 0 eq {
% Read from the file.
DataSource 3 -1 roll setfileposition
DataSource exch readstring pop
} {
% Read from a string or an array of strings.
GlyphData .stringsreadstring
} ifelse
} bind def
/.stringsreadstring % <pos> <string> <strings> .stringsreadstring
% <vmstring>
{ dup type /stringtype eq
{ 3 1 roll length getinterval
}
{ { % Stack: pos string glyphdata
dup 0 get length dup 4 index gt { exit } if
4 -1 roll exch sub 3 1 roll
dup length 1 sub 1 exch getinterval
}
loop
% Stack: pos string glyphdata glyphdata[0]length
% We know no request can span more than 2 strings.
3 index 3 index length add 1 index le
{ % Request fits in a single string: just return a substring.
pop 0 get 3 1 roll length getinterval
}
{ % Request spans 2 strings. Copy the first part.
1 index 0 get 4 index 3 -1 roll 1 index sub getinterval
2 index copy
% Copy the second part.
% Stack: pos str glyphdata str1
length exch 1 get 0 3 index length
3 index sub getinterval 2 index 3 1 roll putinterval
exch pop
}
ifelse
}
ifelse
} bind def
% Interpret a byte string as a (big-endian) integer.
/.cvbsi % <bytes> .cvbsi <int>
{ 0 exch { exch 8 bitshift add } forall
} bind def
% Read an integer from binary data.
/.readint % <pos> <nbytes> .readint <int>
{ string ReadString .cvbsi
} bind def
% ------ CIDFontType 0 ------ %
/.readglyphdata {
currentfont exch .type9mapcid
FDArray exch get exch
} bind def
% BuildGlyph procedure for CIDFontType 0.
% The name %Type9BuildGlyph is known to the interpreter.
/.cid0buildstring 10 string def
(%Type9BuildGlyph) cvn { % <cidfont> <cid> %Type9BuildGlyph -
.currentglobal 3 1 roll 1 index gcheck .setglobal
1 index begin
dup .readglyphdata dup null eq {
% Substitute CID 0. **** WRONG ****
pop pop 0 .readglyphdata
} if
% Stack: cidfont cid subfont charstring
dup null eq { pop pop pop pop } { %**** WRONG ****
4 -1 roll pop
3 1 roll exch dup 4 -1 roll 0 0 moveto
3 index /FontType get 2 eq { .type2execchar } { .type1execchar } ifelse
} ifelse %**** WRONG ****
end
.setglobal
} bind def
% ------ CIDFontType 2 ------ %
% BuildGlyph procedure for CIDFontType 2.
% The name %Type11BuildGlyph is known to the interpreter.
(%Type11BuildGlyph) cvn { % <cidfont> <cid> %Type11BuildGlyph -
% We must be prepared for out-of-range CIDs.
2 copy { .type11mapcid } .internalstopped {
pop /CharStrings get /.notdef get
} if
% Stack: cidfont cid glyphindex
1 index exch .type42execchar
} bind def
% ---------------- Define resources ---------------- %
languagelevel exch 2 .setlanguagelevel
% Define the CIDInit ProcSet resource.
% The ProcSet dictionary is still on the stack.
% We might have loaded CMap support already. However, Adobe's
% protected font downloader defines a CIDInit ProcSet that will be
% loaded from the filesystem later, so we must check specifically
% for the ProcSet being defined in VM.
/CIDInit /ProcSet 2 copy resourcestatus { pop 0 eq } { false } ifelse {
pop pop findresource dup length 4 index length add dict .copydict
4 -1 roll exch .copydict
} {
3 -1 roll
} ifelse exch defineresource pop
% Define the CIDFont resource category.
% We break out .buildcidfont because it appears that at least for
% Type 32 (CIDFontType 4) fonts, the font can be registered in the Font
% category with only a CIDFontType and no FontType.
/.buildcidfont { % <name> <fontdict> .buildcidfont
% <name> <cidfont>
dup /CIDFontType get //.cidfonttypes exch get exec
} odef
/.loadcidfontwithoutpop {
dup 4 string .peekstring pop dup (ttcf) eq exch (\000\001\000\000) eq or {
.loadcjkvttcidfont
} {
/CIDFont /Category findresource /.Instances get
dup length 2 div cvi dict .copydict exch
.loadfont
% Stack: <<original-.Instances>>
/CIDFont /Category findresource /.Instances get {% forall
% <<original-.Instances>> key value
2 index 2 index known {
pop pop
} {
pop exch pop /CIDFont findresource exit
} ifelse
} forall
dup /CIDFontName known not {
{Internal Error in .loadcidfontwithoutpop} stop
} if
} ifelse
} bind def
/.loadcidfont {
.loadcidfontwithoutpop pop
} bind def
% Define the name of the CID font map file.
/defaultcidfontmap (CIDFnmap) def
userdict /CIDFontmap 10 dict put
% <dict> <file> .readCIDFontmap <dict>
% Code from gs_fonts.ps::.readFontmap
/.readCIDFontmap {
{ dup token not { closefile exit } if
% This is a hack to get around the absurd habit of MS-DOS editors
% of adding an EOF character at the end of the file.
dup (\032) eq { pop closefile exit } if
1 index token not
{ (CIDFontmap entry for ) print dup =only
( has no associated file or alias name! Giving up.) = flush
{.readCIDFontmap} 0 get 1 .quit
} if
dup type dup /stringtype eq exch /nametype eq or not
{ (CIDFontmap entry for ) print 1 index =only
( has an invalid file or alias name! Giving up.) = flush
{.readCIDFontmap} 0 get 1 .quit
} if
% stack: dict file cidfontname filename|aliasname
1 index type /stringtype eq
1 index type /nametype eq and 1 index xcheck and
1 index /run eq 2 index /.runlibfile eq or and {
% This is an inclusion entry.
pop findlibfile { exch pop } { file } ifelse
2 index exch .readCIDFontmap pop
} {
% This is a real entry.
% stack: dict file cidfontname filename|aliasname
% Before staring a game, we need a hack.
% Some CJK pdf file contains a cidfontname that cannot
% be represented as a nametype literal. Instead, the
% cidfontname is represented as a string literal.
% If a cidfontname is represented as a stringtype object,
% it must be converted to a nametype object.
% We handle such a case here.
exch dup type /stringtype eq {cvn} if exch
% stack: dict file cidfontname filename|aliasname
% Read and pop tokens until a semicolon.
{ 2 index token not
{ (CIDFontmap entry for ) print 1 index =only
( ends prematurely! Giving up.) = flush
{.readCIDFontmap} 0 get 1 .quit
} if
dup /; eq { pop 3 index 3 1 roll .growput exit } if
% Format:
% /CIDFontname (file) ttc-index ;
% /CIDFontname (file) /Code->CID-dict ;
% /CIDFontname (file) ttc-index /Code->CID-dict ;
%
% e.g.
% /HG-MinchoL (hgminchol.ttc) 1 /Adobe-Japan1-Unicode ;
% /HG-PMinchoL (hgminchol.ttc) 2 /Adobe-Japan1-Unicode ;
% /HG-MinchoL-J2 (hgminchol.ttc) 1 /Adobe-Japan2-Unicode ;
% /HG-PGothicB (hggothicb.ttc) 2 ;
% /HG-GothicB-J2 (hggothicb.ttc) /Adobe-Japan2-Unicode ;
%
% CID Fontmap entry is stored into CIDFontmap dict as an array.
% Array format:
% [filename ttc-index]
% [filename /Code->CID-dict]
% [filename ttc-index /Code->CID-dict]
%
% Type:
% filename: string
% ttc-index: integer
% /Code->CID-dict: name
%
% stack: dict file cidfontname filename something
1 index type /nametype eq {
(CIDFontmap entry for ) print 2 index =only
(defines an alias! Giving up.) = flush
{.readCIDFontmap} 0 get 1 .quit
} if
% stack: dict file cidfontname filename something
exch [ exch 3 -1 roll
% stack: dict file cidfontname [ filename something
dup type /integertype eq {
% stack: dict file cidfontname [ filename int
% Read next token
4 index token not
{ (CIDFontmap entry for ) print 3 index =only
( ends prematurely! Giving up.) = flush
{.readCIDFontmap} 0 get 1 .quit
} if
} if
% stack: dict file cidfontname [ filename int something
% or dict file cidfontname [ filename something
dup /; eq not 1 index type /nametype eq and {
% stack: dict file cidfontname [ filename /Code->CID
% or dict file cidfontname [ filename int /Code->CID
% Read next token
counttomark 2 eq {4} {5} ifelse index token not
{ (CIDFontmap entry for ) print
counttomark 2 eq {3} {4} ifelse index =only
( ends prematurely! Giving up.) = flush
{.readCIDFontmap} 0 get 1 .quit
} if
} if
% stack: dict file cidfontname [ filename int /Code->CID something
% or dict file cidfontname [ filename /Code->CID something
dup /; eq {
pop ]
3 index 3 1 roll .growput exit
} if
pop
} loop
} ifelse
} loop
} bind def
% <file> .loadCIDFontmap -
/.loadCIDFontmap {
userdict /CIDFontmap get exch
.readCIDFontmap pop
} bind def
% Code from .loadinitialfonts
/.loadinitialcidfonts
{ NOCIDFONTMAP not
{ /CIDFONTMAP where
{ pop [ CIDFONTMAP .pathlist ]
{
dup VMDEBUG findlibfile
{ exch pop .loadCIDFontmap }
{ /undefinedfilename signalerror }
ifelse
}
}
{ LIBPATH
{
defaultcidfontmap 1 index .filenamedirseparator
exch concatstrings concatstrings dup VMDEBUG
(r) { file } .internalstopped
{ pop pop } { .loadCIDFontmap } ifelse
}
}
ifelse forall
}
if
%%% Do nothing
} bind def
.loadinitialcidfonts
/CIDFontmapHandler <<
/nametype {
/CIDFont findresource
/CIDFont defineresource pop
} bind
/stringtype {
findlibfile {
exch pop
% Define CIDFont with a name defined in the font file
.loadcidfontwithoutpop
% Define CIDFont with a name define in CIDFontmap
dup length 0 ne {
dup /CIDFontName get 2 index eq {
% Avoid duplicated defineresource for the same CIDFont
pop pop
} {
% Give a name different from the name defined in the file
/CIDFont defineresource pop
} ifelse
} {
pop pop
} ifelse
} {
/undefinedresource signalerror
} ifelse
} bind
/arraytype {
% Replace filename in the array with file
dup 0 get
findlibfile {
3 1 roll pop
copyarray dup 3 1 roll 0
3 -1 roll put
% Expand array
aload pop .loadcjkvttcidfont
/CIDFont defineresource pop
} {
/undefinedresource signalerror
} ifelse
} bind
>> def
%%% CIDFontmap Public Interface
% /CIDFontName .CIDFontmapKnown true|false
/.CIDFontmapKnown {
userdict /CIDFontmap get exch known
} bind def
% /CIDFontName .CIDFontmapKnownget value true
% /CIDFontName .CIDFontmapKnownget false
/.CIDFontmapKnownget {
userdict /CIDFontmap get exch .knownget
} bind def
% /CIDFontName value .CIDFontmapRunHandler -
/.CIDFontmapRunHandler {
dup CIDFontmapHandler exch type get .execasresource
} bind def
% proc .CIDFontmapForAll -
/.CIDFontmapForAll {
CIDFontmap exch forall
} bind def
% proc .CIDFontmapForAllKey -
/.CIDFontmapForAllKey {
[ /pop cvx 3 -1 roll /exec cvx ] cvx .CIDFontmapForAll
} bind def
/CIDFont /Generic /Category findresource dup length dict .copydict
dup /InstanceType /dicttype put
dup /DefineResource {
.buildcidfont
/Generic /Category findresource /DefineResource get exec
} put
/.originalresourceforall 1 index /ResourceForAll get def
dup /ResourceForAll {
currentglobal false setglobal
% (template) (proc) (scratch) g
[ % (template) (proc) (scratch) g [
%
% 1. Gather CIDFont name in /Resource/CIDFont
%
4 index % (template) (proc) (scratch) g [ (template)
{cvn} % (template) (proc) (scratch) g [ (template) {cvn}
4 index % (template) (proc) (scratch) g [ (template) {cvn} (scratch)
.originalresourceforall
% (template) (proc) (scratch) g [ ...
%
% 2. Gather CIDFont name in CIDFontmap
%
{
dup length string cvs
dup % (template) (proc) (scratch) g [ ... (Key) (Key)
counttomark 4 add index
% (template) (proc) (scratch) g [ ... (Key) (Key) (template)
.stringmatch {
cvn
% (template) (proc) (scratch) g [ ... /Key
% 3. Remove duplicated /Key
counttomark -1 1 {
index 1 index eq {
pop exit % Duplicated
} if
} for
} {
pop
} ifelse
} .CIDFontmapForAllKey
]
exch setglobal
%
% 4. Build extended procedure
%
% (template) (proc) (scratch) [CIDFontmapKeys]
4 -1 roll pop
% (proc) (scratch) [CIDFontmapKeys]
3 1 roll
% [CIDFontmapKeys] (proc) (scratch)
[ exch {cvs} aload pop
% [CIDFontmapKeys] (proc) [ (scratch) -cvs-
4 -1 roll aload pop ] cvx
% [CIDFontmapKeys] proc++
%
% 5. Exec
%
forall
} put
% CIDFonts may be defined in CFF OpenType files.
% Check for this here.
/.loadcidfontresource {
dup .ResourceFile {
{.loadcidfont} .execasresource
} {
pop dup
.CIDFontmapKnownget {
.CIDFontmapRunHandler
} {
dup /undefinedresource signalerror
} ifelse
} ifelse
} bind def
dup /.LoadResource {
currentglobal {
.loadcidfontresource
} {
true setglobal {.loadcidfontresource} stopped false setglobal {stop} if
} ifelse
} bind put
dup /.ResourceFileStatus {
dup .CIDFontmapKnown {
pop 2 -1 true
} {
.ResourceFile { closefile 2 -1 true } { pop false } ifelse
} ifelse
} bind put
/Category defineresource pop
% Add the new FontType resources.
9 1 11 { dup /FontType defineresource pop } for
% Add the new FMapType resource.
9 dup /FMapType defineresource pop
% Define the CIDMap resource category.
% These aren't documented, but it's clear what they are for:
% to give names to CIDMaps for CIDFontType 2 fonts.
/CIDMap /Generic /Category findresource dup length dict .copydict
dup /.CheckResource {
% Allow a string, an array of strings, or (as of Adobe release 3011)
% a dictionary.
dup type dup dup /stringtype eq exch /dicttype eq or {
pop true
} {
dup /arraytype eq exch /packedarraytype eq or {
true exch { type /stringtype eq and } forall
} {
false
} ifelse
} ifelse
} bind put
/Category defineresource pop
.setlanguagelevel